/*
 * Copyright 2012 Seitenbau
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.seitenbau.jenkins.plugins.dynamicparameter;

import hudson.Plugin;
import hudson.model.Hudson;
import hudson.model.AbstractProject;
import hudson.model.ParameterDefinition;

import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;

import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;

import org.apache.commons.lang.ObjectUtils;
import com.seitenbau.jenkins.plugins.dynamicparameter.util.JenkinsUtils;

/**
 * An object for obtaining the values for a cascading choice based on the value of the parent parameter.
 * Note: the child property being accessed here is configured via the CascadingChoiceParameterDefinition class.
 * @author Madeline Goss - madeline.goss@gmail.com
 */
public class CascadingChoiceParameterValues extends Plugin
{
  /** The name of the project. */
  private String _projectName;
  /** The name of the property. */
  private String _propertyName;
  /** The value of the parent property. */
  private String _parentPropertyValue;

  /**
   * Get the name of the project.
   * @return the project name as string
   */
  public final String getProjectName()
  {
    return _projectName;
  }

  /**
   * Get the name of the property.
   * @return the property name as string
   */
  public final String getPropertyName()
  {
    return _propertyName;
  }

  /**
   * Get the value of the parent property.
   * @return the parent property value as string
   */
  public final String getParentPropertyValue()
  {
    return _parentPropertyValue;
  }
  
  /**
   * Get the project being referenced
   * @return {@code null} if the label of the current project cannot be found
   */
  @SuppressWarnings("rawtypes")
  private AbstractProject getProject()
  {
    Hudson instance = Hudson.getInstance();
    if (instance != null)
    {
      return (AbstractProject) instance.getItem(this.getProjectName());
    }
    return null;
  }

  /**
   * Get the parameter being referenced
   * @return CascadingChoiceParameterDefinition the parameter instance.
   */
  @SuppressWarnings("rawtypes")
  public final CascadingChoiceParameterDefinition getProperty()
  {
    AbstractProject _project = getProject();
    List<ParameterDefinition> parameterDefinitions = JenkinsUtils.getProjectParameterDefinitions(_project);
    for (ParameterDefinition pd : parameterDefinitions)
    {
      if (pd instanceof CascadingChoiceParameterDefinition)
      {
        CascadingChoiceParameterDefinition parameterDefinition = (CascadingChoiceParameterDefinition) pd;
        String pdName = parameterDefinition.getName();
          if (ObjectUtils.equals(pdName, this.getPropertyName()))
          {
            return parameterDefinition;
          }
      }
    }
    return null;
  }

  /**
   * Get the possible choices, generated by the script with the parent property value as arg[0].
   * @return list of values if the script returns a non-null list;
   *         {@link Collections#EMPTY_LIST}, otherwise
   */
  public final List<Object> getChoices()
  {
    CascadingChoiceParameterDefinition cpd = getProperty();
    return cpd.getChoices(getParentPropertyValue());
  }
  
  /**
   * Obtain the properties from the request object, set them in the instance, 
   * and forward the request to the jelly page for display. 
   * @param req
   * @param res
   * @throws ServletException
   * @throws IOException
   */
  public void doGetParameterValues(StaplerRequest req, StaplerResponse res) throws ServletException, IOException 
  {
    _projectName = req.getParameter("projectName");
    _propertyName = req.getParameter("propertyName");
    _parentPropertyValue = req.getParameter("parentPropertyValue");
    req.setAttribute("childProperty", getProperty());
    req.getView(this, "/com/seitenbau/jenkins/plugins/dynamicparameter/CascadingChoiceParameterValues/index.jelly").forward(req, res);
  }
  
}
